package com.price.common.recyclerview

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.core.util.valueIterator
import androidx.recyclerview.widget.RecyclerView
import com.price.common.extend.doCustomCrashListener
import com.price.common.extend.doOnClick
import com.price.common.extend.doOnLongClick
import com.price.common.extend.logError
import com.price.common.recyclerview.listen.OnRecyclerViewItemChildClick
import com.price.common.recyclerview.listen.OnRecyclerViewItemChildLongClick
import com.price.common.recyclerview.listen.OnRecyclerViewItemClick
import com.price.common.recyclerview.listen.OnRecyclerViewItemLongClick

/**
 */
abstract class BaseAdapter<T, VH : BaseViewHolder> : RecyclerView.Adapter<VH> {

    protected var mDatas: MutableList<T> = ArrayList()

    /**
     * item行的点击事件
     */
    protected var mOnRecyclerViewItemClick: OnRecyclerViewItemClick<T>? = null

    /**
     * item行的长按事件
     */
    protected var mOnRecyclerViewItemLongClick: OnRecyclerViewItemLongClick<T>? = null

    /**
     * item行中子控件的点击事件
     */
    protected var mOnRecyclerViewItemChildClick: OnRecyclerViewItemChildClick<T>? = null

    /**
     * item行中子控件的长按事件
     */
    protected var mOnRecyclerViewItemChildLongClick: OnRecyclerViewItemChildLongClick<T>? = null

    /**
     * 用于保存需要设置点击事件的 ViewId
     */
    protected var mChildClickViewIds: LinkedHashSet<Int>? = null

    /**
     * 用于保存需要设置长按点击事件的 ViewId
     */
    protected var mChildLongClickViewIds: LinkedHashSet<Int>? = null

    constructor()
    constructor(datas: MutableList<T>?) {
        if (datas != null) {
            mDatas = datas
        }
    }

    fun add(data: T?) {
        if (data != null) {
            mDatas.add(data)
            notifyDataSetChanged()
        }
    }

    fun addAll(datas: List<T>?) {
        if (datas != null) {
            mDatas.addAll(datas)
            notifyDataSetChanged()
        }
    }

    fun clearData() {
        mDatas.clear()
        notifyDataSetChanged()
    }

    fun removeAt(position: Int) {
        mDatas.removeAt(position)
        notifyDataSetChanged()
    }

    fun remove(data: T) {
        mDatas.remove(data)
        notifyDataSetChanged()
    }

    fun getData(): List<T> {
        return mDatas
    }

    fun setOnRecyclerViewItemClick(onRecyclerViewItemClick: OnRecyclerViewItemClick<T>?) {
        mOnRecyclerViewItemClick = onRecyclerViewItemClick
    }

    fun setOnRecyclerViewItemLongClick(onRecyclerViewItemLongClick: OnRecyclerViewItemLongClick<T>?) {
        mOnRecyclerViewItemLongClick = onRecyclerViewItemLongClick
    }

    fun setOnRecyclerViewItemChildClick(onRecyclerViewItemChildClick: OnRecyclerViewItemChildClick<T>?) {
        mOnRecyclerViewItemChildClick = onRecyclerViewItemChildClick
    }

    fun setOnRecyclerViewItemChildLongClick(onRecyclerViewItemChildLongClick: OnRecyclerViewItemChildLongClick<T>?) {
        mOnRecyclerViewItemChildLongClick = onRecyclerViewItemChildLongClick
    }

    override fun onBindViewHolder(viewHolder: VH, position: Int) {
        runCatching {
            val t = mDatas[position]
            convert(viewHolder, t, position)
        }.onFailure { e ->
            doCustomCrashListener?.onCrash(e)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val viewHolder = onCreateDefViewHolder(parent, viewType)
        bindViewClickListener(viewHolder, viewType)
        return viewHolder
    }

    /**
     * Override this method and return your ViewHolder.
     */
    protected abstract fun onCreateDefViewHolder(parent: ViewGroup, viewType: Int): VH
    protected abstract fun convert(viewHolder: VH, t: T, position: Int)
    override fun getItemCount(): Int {
        return mDatas.size
    }

    protected fun createBaseViewHolder(parent: ViewGroup, @LayoutRes layoutResId: Int): VH {
        return BaseViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(layoutResId, parent, false)
        ) as VH
    }

    /**
     * 绑定监听事件
     *
     * @param viewHolder
     * @param viewType
     */
    private fun bindViewClickListener(viewHolder: VH, viewType: Int) {
        bindViewItemClickListener(viewHolder)
        bindViewItemChildClickListener(viewHolder)
    }

    private fun bindViewItemChildClickListener(viewHolder: VH) {
        if (mOnRecyclerViewItemChildClick != null && mChildClickViewIds != null) {
            for (viewId in mChildClickViewIds!!) {
                val viewChild: View? = viewHolder.getViewOrNull(viewId)

                viewChild?.doOnClick { v: View? ->
                    val position: Int = viewHolder.adapterPosition
                    val t = getDataByPosition(position)
                    mOnRecyclerViewItemChildClick?.OnItemChildClick(v, t, position)
                }

            }
        }
        if (mOnRecyclerViewItemChildLongClick != null && mChildLongClickViewIds != null) {
            for (viewId in mChildLongClickViewIds!!) {
                val viewChild: View? = viewHolder.getViewOrNull(viewId)
                viewChild?.doOnLongClick { v->
                    val position: Int = viewHolder.adapterPosition
                    val t = getDataByPosition(position)
                    mOnRecyclerViewItemChildLongClick?.OnItemChildLongClick(v, t, position)
                }
            }
        }
    }

    private fun bindViewItemClickListener(viewHolder: VH) {
        if (mOnRecyclerViewItemClick != null) {
            viewHolder.itemView.doOnClick { v->
                val position: Int = viewHolder.adapterPosition
                val t = getDataByPosition(position)
                mOnRecyclerViewItemClick?.OnItemClick(v, t, position)
            }
        }
        if (mOnRecyclerViewItemLongClick != null) {
            viewHolder.itemView.doOnLongClick { v->
                val position: Int = viewHolder.adapterPosition
                val t = getDataByPosition(position)
                mOnRecyclerViewItemLongClick?.OnItemLongClick(v, t, position)
            }
        }
    }

    public fun getDataByPosition(position: Int): T? {
        var t: T? = null
        if (position != RecyclerView.NO_POSITION) {
            t = mDatas[position]
        }
        return t
    }

    /**
     * 设置需要点击事件的子view
     *  需要在onCreateViewHolder中设置
     * @param viewIds intArray
     */
    protected fun addChildClickViewIds(@IdRes vararg viewIds: Int) {
        if (mChildClickViewIds == null) {
            mChildClickViewIds = LinkedHashSet()
        }
        for (viewId in viewIds) {
            mChildClickViewIds?.add(viewId)
        }
    }

    /**
     * 设置需要长按点击事件的子view
     *
     * @param viewIds intArray
     */
    protected fun addChildLongClickViewIds(@IdRes vararg viewIds: Int) {
        if (mChildLongClickViewIds == null) {
            mChildLongClickViewIds = LinkedHashSet()
        }
        for (viewId in viewIds) {
            mChildLongClickViewIds?.add(viewId)
        }
    }


    override fun onViewRecycled(holder: VH) {
        super.onViewRecycled(holder)
//        try {
//            for (view in holder.views.valueIterator()) {
//                when (view) {
//                    is ImageView -> view.setImageDrawable(null)
//                }
//                view.setOnClickListener(null)
//                view.setOnLongClickListener(null)
//            }
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
    }
}
